package com.applabs.dnd.core;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.provider.BaseColumns;
import android.provider.ContactsContract;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class DNDMeService extends Service implements OnSharedPreferenceChangeListener{

	private static final String TAG = "DNDMeService";
	SharedPreferences mSharedPref = null;
	
	private static int currentRingerSetting;
	public static int SERVICE_NOTIFICATION_ID = 1;
	private static BroadcastReceiver mReceiver = null;
	private int DND_ALL_CALLS = 1;
	private int DND_ONLY_PHONEBOOK = 2;
	private int DND_ONLY_UNKNOWN = 3;

	@Override
    public void onCreate() {
		Log.d(TAG,"onCreate() entry");
		mSharedPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		mSharedPref.registerOnSharedPreferenceChangeListener(this);
		boolean bDNDEnabled = false;
		bDNDEnabled = mSharedPref.getBoolean("dnd_checkbox_preference", false);
		if ( bDNDEnabled )
		{
			applyModifiedSettings(mSharedPref);
		}
    }

	@Override
    public void onDestroy() {
		Toast.makeText(this, "DNDMeService Stopped", Toast.LENGTH_SHORT).show();
		Log.d(TAG, "onDestroy entry");
		mSharedPref.unregisterOnSharedPreferenceChangeListener(this);
		stopListening();
    }

	@Override
    public IBinder onBind(Intent intent) {
	    // TODO Auto-generated method stub
	    return null;
    }

	 @Override
	 public void onStart(Intent intent, int startid) {
	 	Toast.makeText(this, "DNDMeService Started", Toast.LENGTH_SHORT).show();
		Log.d(TAG, "onStart");
		startListening(); 
	 }
	 
	 private void startListening()
	 {
		 Log.d(TAG,"startListening() Entry");
		 showNotification();
	 }
	 
	 @SuppressWarnings("deprecation")
	private void showNotification()
	 {
		Log.d(TAG,"showNotification() entry");
		Context ctx = this;
		final String appName = (String) ctx.getResources().getText(com.applabs.dnd.R.string.app_name);
		final String noteText = (String) ctx.getResources().getText(com.applabs.dnd.R.string.app_name);
		int iconRes = com.applabs.dnd.R.drawable.dndoff;
		
		
		Notification note = new Notification(iconRes, appName, System.currentTimeMillis());
		note.flags = Notification.FLAG_FOREGROUND_SERVICE;
	
		Intent noteIntent = new Intent(this, com.applabs.dnd.ui.DNDMeMain.class);
		noteIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
	
		PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0, noteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
	
		note.setLatestEventInfo(ctx, appName, noteText, contentIntent);
	
		this.startForeground(DNDMeService.SERVICE_NOTIFICATION_ID, note);	
	 }
	 
	@Override
    public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
	    // TODO Auto-generated method stub
	    
    }

	private void applyCallSettings(SharedPreferences prefs)
	{
		boolean bDNDCall = false;
		bDNDCall = prefs.getBoolean("call_checkbox_preference", false);
		if ( bDNDCall )
		{
			Log.d(TAG,"onSharedPreferenceChanged Call Enabled");
			startCallListening();
		}
		else
		{
			Log.d(TAG,"onSharedPreferenceChanged Call Disabled");
			stopCallListening();
		}
	}
	
	private void applySMSSettings(SharedPreferences prefs)
	{
		boolean bDNDSms = false;
		bDNDSms = prefs.getBoolean("sms_checkbox_preference", false);
		if ( bDNDSms )
		{
			Log.d(TAG,"onSharedPreferenceChanged SMS Enabled");
			startSMSListening();
		}
		else
		{
			Log.d(TAG,"onSharedPreferenceChanged SMS Disabled");
			stopSMSListening();
		}
	}
	
	private void silentTheCall()
	{
		Log.d(TAG,"silentTheCall() Entry");
		
		AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
		
		try 
		{
			currentRingerSetting = audioManager.getRingerMode();
			Log.d(TAG,"Original Ringer Mode : " + audioManager.getRingerMode());
			audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
		}
		catch (Exception e)
		{
			Log.e(TAG, "Exception in setting ringer mode = " + e.toString());
		}
		finally 
		{
			audioManager.setRingerMode(currentRingerSetting);
		}
		
		Log.d(TAG,"silentTheCall() Exit");
	}
	
	private boolean isPhoneBookNumber(String phoneNumber)
	{
		boolean bFound = false;
		//Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
		    
		ContentResolver contentResolver = getContentResolver();
		Cursor contactLookup = contentResolver.query(
				Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)), 
				new String[] {BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME }, 
				null, 
				null, 
				null);
		
		if ( contactLookup != null && contactLookup.getCount() > 0 )
		{
			Log.d(TAG,"isPhoneBookNumber: " + phoneNumber + " found in contacts");
			bFound = true;
		}
		
		return bFound;
	}
	
	PhoneStateListener phoneStateListener = new PhoneStateListener() {
	    @Override
	    public void onCallStateChanged(int state, String incomingNumber) {
	    	
	        if ( state == TelephonyManager.CALL_STATE_RINGING ) {
	        	
	        	Log.d(TAG, incomingNumber + " is calling!");
	        	
	        	SharedPreferences sharedPreference = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
	        	
	        	String selLang = sharedPreference.getString("call_list_preference", "1");
	        	Log.d(TAG,"Selected Language : "+selLang);
	        	
	            int callSetVal = Integer.parseInt(selLang);
	        	//int callSetVal = sharedPreference.getInt("call_list_preference", 1);
	            //Log.d(TAG,"Integer CallSetValue : "+callSetVal);
	            
	            if ( callSetVal == DND_ALL_CALLS )
	            {
	            	silentTheCall();
	            }
	            else if ( callSetVal == DND_ONLY_PHONEBOOK )
	            {
	            	Log.d(TAG,"DND PhoneBook is ON");
	            	if( isPhoneBookNumber(incomingNumber) )
		        	{
		        		silentTheCall();
		        	}
	            }
	            else if ( callSetVal == DND_ONLY_UNKNOWN )
	            {
	            	Log.d(TAG,"DND Unknown is ON");
	            	if( !isPhoneBookNumber(incomingNumber) )
		        	{
	            		silentTheCall();
		        	}
	            }
	        	
	        } 
	        else if ( state == TelephonyManager.CALL_STATE_IDLE ) {
	            //Not in call: Play music
	        }
	        else if ( state == TelephonyManager.CALL_STATE_OFFHOOK ) {
	            //A call is dialing, active or on hold
	        }
	        super.onCallStateChanged(state, incomingNumber);
	    }
	};
	
	private void startCallListening()
	{
		Log.d(TAG,"startCallListening() Entry");
		TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		if( mgr != null ) {
		    mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
		}
	}
	
	private void stopListening()
	{
		Log.d(TAG,"stopListening() Entry");
		stopCallListening();
		stopSMSListening();
		
	}
	
	private void stopCallListening()
	{
		Log.d(TAG,"stopCallListening() Entry");
		AudioManager audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
		audioManager.setRingerMode(currentRingerSetting);
		TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
		if( mgr != null ) {
		    mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE);
		}
	}
	
	private void startSMSListening()
	{
		mReceiver = new BroadcastReceiver() 
		{
			@Override
			public void onReceive(Context context, Intent intent) {
				String action = intent.getAction();
				
				if( action.equals("android.provider.Telephony.SMS_RECEIVED") ) {
					//action for sms received
					Log.d(TAG,"SMS Received!!");

					Bundle bundle = intent.getExtras();
			    	  
					if ( bundle != null ) {
						//---retrieve the SMS message received---
						Object[] pdus = (Object[]) bundle.get("pdus");
						Log.d(TAG,"SMS Count Received : " + pdus.length);
						final SmsMessage[] msgs = new SmsMessage[pdus.length];
						
						for (int i = 0; i < msgs.length; i++) 
						{  
							String phNumber=null;
			            	  
							msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);                
			                  
							phNumber = msgs[i].getOriginatingAddress();
			                  
							Log.d(TAG,"SMS from " + phNumber);
			                  
							if( isPhoneBookNumber(phNumber) )
							{
								Log.d(TAG,"SmsReceived from PhoneBook Number");
							}
							else
							{
								Log.d(TAG,"SmsReceived from Unknown Number");
							}
						}
					}
				}
				else if( action.equals(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED) ) {
					//action for phone state changed
				}     
			}
		};
		
		Log.d(TAG,"startSMSListening() Entry");
		IntentFilter filter = new IntentFilter();
		filter.addAction("android.provider.Telephony.SMS_RECEIVED");
		//filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
		registerReceiver(mReceiver, filter);
	
	}
	
	private void stopSMSListening()
	{
		Log.d(TAG,"stopSMSListening() Entry");
		
		if ( mReceiver != null )
		{
			unregisterReceiver(mReceiver);
			mReceiver = null;
		}
	}
	
	private void applyModifiedSettings(SharedPreferences prefs)
	{
		applyCallSettings(prefs);
		applySMSSettings(prefs);
	}
	
}
